﻿
package extremefx.i18n {
	/**
	 * @author Marcelo Volmaro
	 */
	internal class CCJulian {
		private static const EPOCH:int = -1;
		
		public static function _isLeapYear(pYear:int):Boolean {
			return CCMath.mod(pYear, 4) == (pYear > 0 ? 0 : 3);
		}
		
		public static function _fixedFromDMY(pDay:int, pMonth:int, pYear:int):int {
			var y:int = pYear < 0 ? pYear+1 : pYear;
			var k:int = EPOCH - 1;
			k += 365 * (y-1);
			k += CCMath.div(y-1, 4);
			k += CCMath.div(367*pMonth-362, 12);
			
			if (pMonth > 2) {
				k += _isLeapYear(pYear) ? -1 : -2;
			}
			
			return k + pDay;
		}
		
		public static function _yearFromFixed(pDate:int):int{
			var approx:int = CCMath.div(4*(pDate-EPOCH)+1464, 1461);
			return approx <= 0 ? approx - 1 : approx;
		}
		
		private static function _myFromFixed(pDate:int):Array {
			var year:int = _yearFromFixed(pDate);
			var priorDays:int = pDate - _fixedFromDMY(1, 1, year);
			
			var correction:int;
			
			if (pDate < _fixedFromDMY(1, 3, year)) {
				correction = 0;
				
			} else if (_isLeapYear(year)) {
				correction = 1;
				
			} else {
				correction = 2;
			}
	
			var month:int = CCMath.div(12 * (priorDays + correction) + 373, 367);
			return [year, month];
		}
		
		public static function _dmyFromFixed(pDate:int):Array {
			var out:Array = _myFromFixed(pDate);
			out.push(pDate - _fixedFromDMY(1, int(out[1]), int(out[0])) + 1);
			return out;
		}
		
		public static function _monthFromFixed(pDate:int):int {
			var out:Array = _myFromFixed(pDate);
			return int(out[1]);
		}
		
		public static function _dayFromFixed(pDate:int):int {
			var out:Array = _dmyFromFixed(pDate);
			return int(out[2]);
		}		
	}
}
